#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include "amever.h"
#include "utils.h"
#include <arpa/inet.h>

inline void __attribute__ ((format (printf, 1, 2))) amelog(const char *fmt, ...)
{
#if (_AME_DEBUG==1)
    va_list ap;
    va_start(ap, fmt);
    char buffy[255], newfmt[128];
    sprintf(newfmt, "%010u : %s", s.clock, fmt);
    int size = vsprintf(buffy, newfmt, ap);

    // Output to stdout
    write (0, buffy, size);
#ifdef WRITE_LOG
    if (s.logfile) {
					write(s.logfile, buffy, size);
    }
    else {
    	// printf("Couldn't write to file\n");
    }
#endif
    va_end(ap);
    fflush(0);
#endif
}

inline void __attribute__ ((format (printf, 1, 2))) amelog_noTS(const char *fmt, ...)
{
#if (_AME_DEBUG==1)
    va_list ap;
    va_start(ap, fmt);
    char buffy[255], newfmt[128];
    sprintf(newfmt, "%010u : %s", s.clock, fmt);
    int size = vsprintf(buffy, newfmt, ap);

    // Output to stdout
    write (0, buffy, size);

    if (s.logfile) {
					write(s.logfile, buffy, size);
    }
    else {
    	// printf("Couldn't write to file\n");
    }
    va_end(ap);
#endif
}


inline int WFIFOPR(struct client *me, int size) {
	if (!me || !me->wbuffer)
		return 0;
	// Prepare buffer for writing
	if ((me->wbuffer->size - 255) > me->wbuffer->mark + size)
		return size;
	// Try to realloc
	if (buffer_realloc(me->wbuffer, size + 255)) {
		amelog("Client [%d](charid[%d]) is requiring too much buffer, eof set.\n", me->fd, me->userid);
		me->eof = 1; /* Requireing too much write buffer, closing */
		return 0;
	}
	return size;
}

inline int RFIFOPR(struct client *me, int size) {
	if (!me || !me->wbuffer)
		return 0;
	// Prepare buffer for reading
	if ((me->rbuffer->size - 255) > me->rbuffer->mark + size)
		return size;
	// Try to realloc
	if (buffer_realloc(me->rbuffer, size + 255)) {
		amelog("Client [%d](charid[%d]) is requiring too much buffer, eof set.\n", me->fd, me->userid);
		me->eof = 1; /* Requireing too much write buffer, closing */
		return 1;
	}
	return size;
}

inline void WFIFOSP(struct client *me, int pos) {
	// Sets the new point
	if (!me || !pos || me->eof)
		return;
	me->wbuffer->mark+=pos;
}

int readConf(const char *fp) {
	amelog("Reading %s\n", fp);
	int count = 0;
	FILE *fh;
	if ((fh = fopen(fp, "r")) == NULL) {
		amelog("Couldn't open %s\n", fp);
		return 0;
	}

	struct globalOptions go[] = {
		{ "input_ip", &(s.config.input_ip), T_STR },
		{ "input_port", &(s.config.input_port), T_U16 },
		{ "db_host", &(s.config.db_host), T_STR },
		{ "db_user", &(s.config.db_user), T_STR },
		{ "db_pass", &(s.config.db_pass), T_STR },
		{ "db_name", &(s.config.db_name), T_STR },
		{ 0, 0, 0 }
	};

	char w1[128], w2[1024-128];
	while (fgets(s.buffy, 1024, fh)) {
		if (sscanf(s.buffy,"%[^=]=%[^\n\r]",w1,w2) == 2) {
			int i;
			for (i=0;go[i].type != T_VOD;i++) {
				if (!strcasecmp(go[i].key, w1)) {
					switch (go[i].type) {
						case T_U16:
							*((unsigned short *)(go[i].val)) = (unsigned short)strtol(w2, 0, 0);
							amelog("%s is set to %d\n", w1, *((unsigned short *)(go[i].val)));
							break;
						case T_U32:
							*(unsigned int *)go[i].val = (unsigned int)strtol(w2, 0, 0);
							break;
						case T_S16:
							*(signed short *)go[i].val = (signed short)strtol(w2, 0, 0);
							break;
						case T_S32:
							*(signed int *)go[i].val = (signed int)strtol(w2, 0, 0);
							break;
						case T_STR:
							strcpy(go[i].val, w2);
							amelog("%s is set to %s\n", w1, (const char *)go[i].val);
							break;
						case T_VOD:
						default:
							break;
					}
					count ++;
					break;
				}
			}
		}
		else if (sscanf(s.buffy, "ban(%[0-9/\\.])", w2) == 1) {
			int i;
			for(i=0;i<MAX_BAN_LIST;i++)
			{
				if (s.network_banList[i] == 0)
				{
					s.network_banList[i] = inet_addr(w2);
					break;
				}
			}
		}
		else if (sscanf(s.buffy, "include(%[a-zA-Z0-9/\\.])", w2) == 1) {
			count += readConf(w2);
		}
		else if (sscanf(s.buffy, "lua(%[a-zA-Z0-9/\\.])", w2) == 1) {
			if (s.L != 0)
				lua_dofile(s.L, w2);
			else
				amelog("Lua is not inited yet...\n");
		}
		else if (sscanf(s.buffy, "map(%[a-zA-Z0-9/\\.])", w2) == 1) {
			if (s.maps) {
				amelog("Trying to init map %s\n", w2);
				server_registerMap(w2, 0);
			}
			else {
				amelog("Maps not set yet.\n");
			}
		}
		else if (s.buffy[0] != '#' && s.buffy[0] != '/' && s.buffy[0] != ';' && s.buffy[0] != '\r' && s.buffy[0] != '\n' && s.buffy[0] != ' ') {
			// Looky how many comments you can use :)
			sscanf(s.buffy, "%[^\n\r]", w1);
			amelog("Config line '%s' in %s feels wierd.\n", w1, fp);
		}
	}
	fclose(fh);
	return count;
}
